package com.blue.integration.pay.swift;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

import com.blue.core.http.HttpInvoker;
import com.blue.integration.pay.PayClient;
import com.blue.integration.pay.PayException;
import com.blue.integration.pay.PayNotify;
import com.blue.integration.pay.PayRequest;
import com.blue.integration.pay.PayResponse;

/**
 * 威富通支会接口
 *
 * @author zhengjin
 * @since 1.0 2017年12月14日
 */
public class SwiftPayClient implements PayClient, InitializingBean
{
	private static Logger logger = LoggerFactory.getLogger(SwiftPayClient.class);

	private HttpInvoker httpInvoker;
	private String url;
	private String jspayUrl;
	private Map<String, SwiftConfig> configMap = new HashMap<>();

	public SwiftPayClient()
	{
	}

	@Override
	public PayResponse pay(PayRequest request)
	{
		Assert.notNull(request, "请求参数不能为空");
		if (!(request instanceof SwiftPayRequest))
			throw new PayException("请求参数不是 " + SwiftPayRequest.class.getSimpleName() + " 类型");

		SwiftPayRequest swiftPayRequest = (SwiftPayRequest) request;
		SwiftConfig config = configMap.get(swiftPayRequest.getMch());
		if (config == null)
			throw new PayException("找不到支付商户配置：" + swiftPayRequest.getMch());

		XmlSwiftPayRequest xmlSwiftPayRequest = XmlSwiftPayRequest.toRequest(swiftPayRequest, config);
		String xml = SwiftPayUtil.toXml(xmlSwiftPayRequest, config.getKey());
		logger.info("请求报文：{}", xml);
		String retXml = null;
		try
		{
			retXml =httpInvoker.post(url, xml);
		}
		catch (Exception e)
		{
			logger.error("调用支付接口出错：", e);
			throw new PayException(e);
		}
		logger.info("返回报文：{}", retXml);
		XmlSwiftPayResponse xmlSwiftPayResponse = SwiftPayUtil.toObject(XmlSwiftPayResponse.class, config.getKey(), retXml);
		SwiftPayResponse swiftPayResponse = xmlSwiftPayResponse.toResponse();
		swiftPayResponse.setOrderNo(swiftPayRequest.getOrderNo());
		swiftPayResponse.setMoney(swiftPayRequest.getMoney());
		swiftPayResponse.setJspayUrl(String.format("%s?token_id=%s&showwxtitle=1", jspayUrl, xmlSwiftPayResponse.getTokenId()));
		return swiftPayResponse;
	}

	@Override
	public PayNotify notify(String mch, String xml)
	{
		Assert.hasText(mch, "商户代码不能为空");
		Assert.hasText(xml, "XML报文不能为空");
		SwiftConfig config = configMap.get(mch);
		if (config == null)
			throw new PayException("找不到支付商户配置：" + mch);

		XmlSwiftNotify swiftNotify = SwiftPayUtil.toObject(XmlSwiftNotify.class, config.getKey(), xml);
		PayNotify payNotify = swiftNotify.toNotify();
		return payNotify;
	}

	public void setHttpInvoker(HttpInvoker httpInvoker)
	{
		this.httpInvoker = httpInvoker;
	}

	public void setUrl(String url)
	{
		this.url = url;
	}

	public void setJspayUrl(String jspayUrl)
	{
		this.jspayUrl = jspayUrl;
	}

	public void setConfigs(List<SwiftConfig> configList)
	{
		if (configList == null || configList.isEmpty())
			return;

		for (SwiftConfig config : configList)
		{
			configMap.put(config.getMch(), config);
		}
	}

	@Override
	public void afterPropertiesSet() throws Exception
	{
		if (configMap == null || configMap.isEmpty())
			throw new IllegalArgumentException("威富通支付接口缺少配置");

		if (url == null || url.isEmpty())
			throw new IllegalArgumentException("威富通支付接口缺少URL");

		if (jspayUrl == null || jspayUrl.isEmpty())
			throw new IllegalArgumentException("威富通支付接口缺少js支付URL");

	}
}
